package yunjiao.javatutorials.guava.base.functional;

import com.google.common.base.Equivalence;

import java.time.LocalDate;
import java.util.*;

/**
 * 复杂对象比较
 *
 * @author yangyunjiao
 */
public class ComplexObjectComparison {

    record Employee(String employeeId, String firstName, String lastName, LocalDate hireDate, Department department) {

        // 复合键：部门+雇佣年份
        public String getDepartmentYearKey() {
            return department.id() + ":" + hireDate.getYear();
        }

        @Override
        public String toString() {
            return String.format("Employee{id='%s', name='%s %s', hireDate=%s, dept=%s}",
                    employeeId, firstName, lastName, hireDate, department.name());
        }
    }

    record Department(String id, String name) {

    }

    public static void main(String[] args) {
        Department engineering = new Department("ENG", "Engineering");
        Department marketing = new Department("MKT", "Marketing");

        List<Employee> employees = Arrays.asList(
                new Employee("E001", "John", "Doe", LocalDate.of(2020, 1, 15), engineering),
                new Employee("E002", "Jane", "Smith", LocalDate.of(2020, 3, 20), engineering),
                new Employee("E003", "Bob", "Johnson", LocalDate.of(2021, 6, 10), marketing),
                new Employee("E004", "Alice", "Brown", LocalDate.of(2020, 8, 5), engineering)
        );

        // 基于部门和雇佣年份的等价关系
        Equivalence<Employee> deptYearEquivalence =
                Equivalence.equals().onResultOf(Employee::getDepartmentYearKey);

        // 分组统计
        Map<Equivalence.Wrapper<Employee>, List<Employee>> groups = new HashMap<>();
        for (Employee employee : employees) {
            Equivalence.Wrapper<Employee> wrapper = deptYearEquivalence.wrap(employee);
            groups.computeIfAbsent(wrapper, k -> new ArrayList<>()).add(employee);
        }

        System.out.println("按部门和雇佣年份分组:");
        for (Map.Entry<Equivalence.Wrapper<Employee>, List<Employee>> entry : groups.entrySet()) {
            Employee representative = entry.getKey().get();
            List<Employee> group = entry.getValue();
            System.out.printf("部门: %s, 雇佣年份: %d -> 员工数: %d%n",
                    representative.department().name(),
                    representative.hireDate().getYear(),
                    group.size());
        }
    }
}
